package Lambda;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class LambdaNoType {

    //<? extends T> 表示类型的上界，表示参数化类型的可能是T 或是 T的子类;
    //<? super T> 表示类型下界（Java Core中叫超类型限定），表示参数化类型是此类型的超类型（父类型），直至Object;

    //extends 可用于返回类型限定，不能用于参数类型限定（换句话说：? extends xxx 只能用于方法返回类型限定，jdk能够确定此类的最小继承边界为xxx，只要是这个类的父类都能接收，但是传入参数无法确定具体类型，只能接受null的传入）。
    //super 可用于参数类型限定，不能用于返回类型限定（换句话说：? supper xxx 只能用于方法传参，因为jdk能够确定传入为xxx的子类，返回只能用Object类接收）。
    //? 既不能用于方法参数传入，也不能用于方法返回

    // <?  SomeClass>与<T extends SomeClass>的区别:
    // List<String>                        参数化的类型
    // List<E>                             泛型
    // List<?>                             无限制通配符类型
    // <E extends SomeClass>               有限制类型参数
    // List <? extends SomeClass>          有限制通配符类型
    // <T extends Comparable<T>>           递归类型限制
    // static <E> List<E> asList(E[] a)    泛型方法




    public void lambdaNoTypeFun(){
        System.out.println("lambdaNoTypeFun Start");

        {
            //List<? extends Father>表示上限是Father,下面这样的赋值都是合法的
            List<? extends Father> list1 = new ArrayList<Father>();
            List<? extends Father> list2 = new ArrayList<Son>();
            List<? extends Father> list3 = new ArrayList<LeiFeng>();
            System.out.println(list1+"\n"+list2+"\n"+list3+"\n");

            List<Father> ls = new ArrayList();
            ls.add(new Son(1));

            List<Father> list4 = ls;
            list4.add(new Son(4));

            Father father =      list4.get(0);//读取出来的东西只能存放在Father或它的基类里。
            Object object =      list4.get(0);//读取出来的东西只能存放在Father或它的基类里。
            Human  human  =      list4.get(0);//读取出来的东西只能存放在Father或它的基类里。
            Son    son    = (Son)list4.get(0);

            System.out.println(object+"\n"+human+"\n"+father+"\n"+son);
        }

        {
            //super只能添加Father和Father的子类，不能添加Father的父类,读取出来的东西只能存放在Object类里
            List<? super Father> list = new ArrayList();
            list.add(new Father(1));
            list.add(new LeiFeng(2));//compile error
            list.add(new Son(3));

            Object object =         list.get(0);
            Human  human   = (Human) list.get(0);
            Father father  = (Father)list.get(0);
            System.out.println(object+"\n"+human+"\n"+father);
        }

        {
            System.out.println(of1(1,2,3,4,5).toString());
            System.out.println(of1("1","2","3",4,5));
        }
        System.out.println("lambdaNoTypeFun End");
    }

    public static <T extends Comparable<T>> T maximum(T x, T y, T z) {

        T max = x;
        if ( y.compareTo( max ) > 0 ) {
            max = y;
        }
        if ( z.compareTo( max ) > 0 ) {
            max = z;
        }
        return max;
    }

    public <T> List<T> of1(T... t){
        return Arrays.asList(t);
    }

    private static <T>  T[] of2(T values,T...others){
        List<T> s = (List<T>) values;
        for (int i=0;i<others.length;i++){
            s.add(others[i]);
        }
        return (T[]) values;
    }

    //继承关系(派生类->基类)：(LeiFeng & Son) -> Father -> Human
    class Human{
        int a;
        Human(){

        }
        Human(int a){
            this.a=a;
        }
    }
    class Father extends Human{
        Father(){

        }
        Father(int a) {
            super(a);
        }
    }
    class Son extends Father{
        Son(){

        }
        Son(int a) {
            super(a);
        }
    }
    class LeiFeng extends Father {
        LeiFeng(){

        }
        LeiFeng(int a) {
            super(a);
        }
    }




}
